package com.gitee.wsl.compose.ext.text.builder

import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shadow
import androidx.compose.ui.graphics.drawscope.DrawStyle
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.ParagraphStyle
import androidx.compose.ui.text.PlatformParagraphStyle
import androidx.compose.ui.text.PlatformSpanStyle
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontSynthesis
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.intl.LocaleList
import androidx.compose.ui.text.style.BaselineShift
import androidx.compose.ui.text.style.Hyphens
import androidx.compose.ui.text.style.LineBreak
import androidx.compose.ui.text.style.LineHeightStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextDirection
import androidx.compose.ui.text.style.TextGeometricTransform
import androidx.compose.ui.text.style.TextIndent
import androidx.compose.ui.text.style.TextMotion
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.TextUnit


/**
 *  Applies the specified span style to the [AnnotatedString.Builder] and invokes the specified
 *  [block].
 *  @see SpanStyle
 */
inline fun <R : Any> AnnotatedString.Builder.withSpanStyle(
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontWeight: FontWeight? = null,
    fontStyle: androidx.compose.ui.text.font.FontStyle? = null,
    fontSynthesis: FontSynthesis? = null,
    fontFamily: androidx.compose.ui.text.font.FontFamily? = null,
    fontFeatureSettings: String? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    baselineShift: BaselineShift? = null,
    textGeometricTransform: TextGeometricTransform? = null,
    localeList: LocaleList? = null,
    background: Color = Color.Unspecified,
    textDecoration: TextDecoration? = null,
    shadow: Shadow? = null,
    platformStyle: PlatformSpanStyle? = null,
    drawStyle: DrawStyle? = null,
    block: AnnotatedString.Builder.() -> R
): R = withStyle(
    SpanStyle(
        color,
        fontSize,
        fontWeight,
        fontStyle,
        fontSynthesis,
        fontFamily,
        fontFeatureSettings,
        letterSpacing,
        baselineShift,
        textGeometricTransform,
        localeList,
        background,
        textDecoration,
        shadow,
        platformStyle,
        drawStyle
    ), block
)

/**
 *  Applies the specified span style to the [AnnotatedString.Builder] and invokes the specified
 *  [block].
 *  @see SpanStyle
 */
inline fun <R : Any> AnnotatedString.Builder.withSpanStyle(
    brush: Brush?,
    alpha: Float = Float.NaN,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontWeight: FontWeight? = null,
    fontStyle: androidx.compose.ui.text.font.FontStyle? = null,
    fontSynthesis: FontSynthesis? = null,
    fontFamily: androidx.compose.ui.text.font.FontFamily? = null,
    fontFeatureSettings: String? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    baselineShift: BaselineShift? = null,
    textGeometricTransform: TextGeometricTransform? = null,
    localeList: LocaleList? = null,
    background: Color = Color.Unspecified,
    textDecoration: TextDecoration? = null,
    shadow: Shadow? = null,
    platformStyle: PlatformSpanStyle? = null,
    drawStyle: DrawStyle? = null,
    block: AnnotatedString.Builder.() -> R
): R = withStyle(
    SpanStyle(
        brush,
        alpha,
        fontSize,
        fontWeight,
        fontStyle,
        fontSynthesis,
        fontFamily,
        fontFeatureSettings,
        letterSpacing,
        baselineShift,
        textGeometricTransform,
        localeList,
        background,
        textDecoration,
        shadow,
        platformStyle,
        drawStyle
    ), block
)


/**
 *  Applies the specified Paragraph style to the [AnnotatedString.Builder] and invokes the specified
 *  [block].
 *  @see ParagraphStyle
 */
inline fun <R : Any> AnnotatedString.Builder.withParagraphStyle(
    textAlign: TextAlign = TextAlign.Unspecified,
    textDirection: TextDirection = TextDirection.Unspecified,
    lineHeight: TextUnit = TextUnit.Unspecified,
    textIndent: TextIndent? = null,
    platformStyle: PlatformParagraphStyle? = null,
    lineHeightStyle: LineHeightStyle? = null,
    lineBreak: LineBreak = LineBreak.Unspecified,
    hyphens: Hyphens = Hyphens.Unspecified,
    textMotion: TextMotion? = null,
    crossinline block: AnnotatedString.Builder.() -> R
): R = withStyle(
    ParagraphStyle(
        textAlign,
        textDirection,
        lineHeight,
        textIndent,
        platformStyle,
        lineHeightStyle,
        lineBreak,
        hyphens,
        textMotion
    ), block
)


/**
 * Applies the given text style to the receiver [AnnotatedString.Builder] and executes the provided [block].
 *
 * @param style The text style to apply to the receiver [AnnotatedString.Builder].
 * @param block The block of code to execute within the context of the modified [AnnotatedString.Builder].
 * @return The result of executing the [block].
 */
inline fun <R : Any> AnnotatedString.Builder.withStyle(
    style: TextStyle,
    crossinline block: AnnotatedString.Builder.() -> R
): R = withStyle(style.toParagraphStyle()) {
    withStyle(style.toSpanStyle(), block)
}
